/**
 * 
 */
package game.render;

import game.render.screen.GameScr;
import game.render.screen.MessageScr;
import game.render.screen.Screen;
import game.render.screen.WaitScr;

import javax.microedition.lcdui.Graphics;

/**
 * @author Quynh Lam
 * 
 */
public class Canvas extends javax.microedition.lcdui.Canvas implements Runnable {
    public static Canvas instance;
    static boolean bRun;
    // 0 1 2 3 4 5 6 7 8 9 * LSoft RSoft
    public static boolean[] keyPressed = new boolean[14];
    public static boolean[] keyReleased = new boolean[14];
    public static boolean[] keyHold = new boolean[14];
    static boolean isPointerDown;
    static boolean isPointerClick;
    public static int px, py;
    public static int isCheat, gameTick;
    // Width Height Half-W, Half-H, width/3, height/3, 2*width/3, 2*height/2,
    // ...
    public static int w, h, hw, hh, wd3, hd3, w2d3, h2d3, w3d4, h3d4, wd6, hd6;
    public static boolean isMoto;
    public static Screen currentScreen;
    public static GameScr gameScr = new GameScr();
    public static WaitScr waitScr = new WaitScr();
    public static MessageScr messageScr = new MessageScr();

    public Canvas() {
        instance = this;
        this.setFullScreenMode(true);
        System.gc();
        isMoto = (getKeyCode(FIRE) == -20);
        w = this.getWidth();
        h = this.getHeight();
        hw = w / 2;
        hh = h / 2;
        wd3 = w / 3;
        hd3 = h / 3;
        w2d3 = 2 * w / 3;
        h2d3 = 2 * h / 3;
        w3d4 = 3 * w / 4;
        h3d4 = 3 * h / 4;
        wd6 = w / 6;
        hd6 = h / 6;
    }

    public void start() {
        currentScreen = waitScr;
        new Thread(this).start();
    }

    public void run() {
        bRun = true;
        while (bRun) {
            try {
                long l1 = System.currentTimeMillis();
                gameTick++;
                if (gameTick > 10000)
                    gameTick = 0;
                if (currentScreen != null)
                    currentScreen.update();
                repaint();
                serviceRepaints();
                // Synchronize time
                long l2 = System.currentTimeMillis() - l1;
                if (l2 < 50)
                    try {
                        Thread.sleep(50 - l2);
                    } catch (InterruptedException e) {
                    }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // Catch key-down input and save in to Input Array
    protected void keyPressed(int keyCode) {
        if (isMoto) {
            switch (getGameAction(keyCode)) {
            case UP:
                keyHold[2] = true;
                keyPressed[2] = true;
                return;
            case DOWN:
                keyHold[8] = true;
                keyPressed[8] = true;
                return;
            case LEFT:
                keyHold[4] = true;
                keyPressed[4] = true;
                return;
            case RIGHT:
                keyHold[6] = true;
                keyPressed[6] = true;
                return;
            case FIRE:
                keyHold[5] = true;
                keyPressed[5] = true;
                return;
            }
            if (keyCode == -21) // Soft 1
                keyCode = -6;
            else if (keyCode == -22) // Soft 2
                keyCode = -7;
        }
        mapKeyPress(keyCode);
    }

    public void mapKeyPress(int keyCode) {
        switch (keyCode) {
        case 48:
        case 49:
        case 50:
        case 51:
        case 52:
        case 53:
        case 54:
        case 55:
        case 56:
        case 57:
            keyHold[keyCode - 48] = true;
            keyPressed[keyCode - 48] = true;
            return; // 0 -> 9
        case 42:
            keyHold[10] = true;
            keyPressed[10] = true;
            return; // Key [*]
        case 35:
            keyHold[11] = true;
            keyPressed[11] = true;
            return; // Key [#]
        case -6:
        case -21:
            keyHold[12] = true;
            keyPressed[12] = true;
            return; // Soft1
        case -7:
        case -22:
            keyHold[13] = true;
            keyPressed[13] = true;
            return; // Soft2
        case -5:
            keyHold[5] = true;
            keyPressed[5] = true;
            return; // [i]
        }
        switch (getGameAction(keyCode)) {
        case UP:
            keyHold[2] = true;
            keyPressed[2] = true;
            return;
        case DOWN:
            keyHold[8] = true;
            keyPressed[8] = true;
            return;
        case LEFT:
            keyHold[4] = true;
            keyPressed[4] = true;
            return;
        case RIGHT:
            keyHold[6] = true;
            keyPressed[6] = true;
            return;
        case FIRE:
            keyHold[5] = true;
            keyPressed[5] = true;
            return;
        }
    }

    // Catch key-up input and clear from Input Array
    protected void keyReleased(int keyCode) {
        if (isMoto) {
            switch (getGameAction(keyCode)) {
            case UP:
                keyHold[2] = false;
                return;
            case DOWN:
                keyHold[8] = false;
                return;
            case LEFT:
                keyHold[4] = false;
                return;
            case RIGHT:
                keyHold[6] = false;
                return;
            case FIRE:
                keyHold[5] = false;
                return;
            }
            if (keyCode == -21) // Soft 1
                keyCode = -6;
            else if (keyCode == -22) // Soft 2
                keyCode = -7;
        }
        mapKeyRelease(keyCode);
    }

    public void mapKeyRelease(int keyCode) {
        switch (keyCode) {
        case 48:
        case 49:
        case 50:
        case 51:
        case 52:
        case 53:
        case 54:
        case 55:
        case 56:
        case 57:
            keyHold[keyCode - 48] = false;
            keyReleased[keyCode - 48] = true;
            return; // 0 -> 9
        case 42:
            keyHold[10] = false;
            keyReleased[10] = true;
            return; // Key [*]
        case 35:
            keyHold[11] = false;
            keyReleased[11] = true;
            return; // Key [#]
        case -6:
        case -21:
            keyHold[12] = false;
            keyReleased[12] = true;
            return; // Soft1
        case -7:
        case -22:
            keyHold[13] = false;
            keyReleased[13] = true;
            return; // Soft2
        case -5:
            keyHold[5] = false;
            keyReleased[5] = true;
            return; // [i]
        }
        switch (getGameAction(keyCode)) {
        case UP:
            keyHold[2] = false;
            keyReleased[2] = true;
            return;
        case DOWN:
            keyHold[8] = false;
            keyReleased[8] = true;
            return;
        case LEFT:
            keyHold[4] = false;
            keyReleased[4] = true;
            return;
        case RIGHT:
            keyHold[6] = false;
            keyReleased[6] = true;
            return;
        case FIRE:
            keyHold[5] = false;
            keyReleased[5] = true;
            return;
        }
    }

    protected void pointerDragged(int x, int y) {
        px = x;
        py = y;
    }

    protected void pointerPressed(int x, int y) {
        isPointerDown = true;
        px = x;
        py = y;
    }

    protected void pointerReleased(int x, int y) {
        isPointerDown = false;
        isPointerClick = true;
        px = x;
        py = y;
    }

    // Clear all key in Input Array
    static void clearKeyHold() {
        for (int i = 0; i < 14; i++)
            keyHold[i] = false;
    }

    static void clearKeyPressed() {
        isPointerClick = false;
        for (int i = 0; i < 14; i++)
            keyPressed[i] = false;
    }

    protected void paint(Graphics g) {
        if (currentScreen != null)
            currentScreen.paint(g);
    }

    /**
     * @param i
     * @return
     */
    public static int abs(int i) {
        return i > 0 ? i : -i;
    }

}
